package cn.shujuhai.common.pluging.email;

import cn.hutool.core.codec.Base64;
import cn.shujuhai.cms.domain.ToEmail;
import jakarta.activation.DataSource;
import jakarta.activation.FileDataSource;
import jakarta.activation.URLDataSource;
import jakarta.mail.util.ByteArrayDataSource;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;


@Component
@Slf4j
public class HtmlProcessor {

    @Value("${template.url}")
    private String url;

    @Value("${server.servlet.context-path}")
    private String baseUrl;

    /**
     * 处理 HTML 内容，将其中的图片和视频转为 Base64 编码
     *
     * @param htmlContent 原始 HTML 内容
     * @return 处理后的 HTML 内容
     */
    public ToEmail processHtml(String htmlContent) {
        // 解析 HTML 内容
        Document document = Jsoup.parse(htmlContent);
        ToEmail toEmail = new ToEmail();
        Map<String, DataSource> multimedia = new HashMap<>();
        // 处理 <img> 标签
        processImgTags(document, multimedia);
        // 处理 <video> 标签
        processVideoTags(document, multimedia);
        toEmail.setContent(document.html());
        toEmail.setMultimedia(multimedia);
        // 返回修改后的 HTML 内容
        return toEmail;
    }

    /**
     * 处理 HTML 中的 <img> 标签，将图片转为 Base64 编码
     *
     * @param document HTML 文档对象
     */
    private void processImgTags(Document document, Map<String, DataSource> multimedia) {
        Elements imgTags = document.select("img");
        for (Element img : imgTags) {
            String cid = String.valueOf(UUID.randomUUID());
            String imgSrc = img.attr("src");
            img.attr("src", "cid:" + cid);
            img.attr("type", "image/jpeg");
            if (imgSrc.startsWith("data:image/jpeg;base64")) {
                String replace = imgSrc.replace("data:image/jpeg;base64,", "");
                byte[] imageBytes = Base64.decode(replace);
                // 使用 ByteArrayDataSource 创建附件
                DataSource dataSource = new ByteArrayDataSource(imageBytes, "image/jpeg");
                multimedia.put(cid, dataSource);
                continue;
            }
            if (imgSrc.startsWith("http") || imgSrc.startsWith("https")) {
                DataSource dataSource = getDataSource(imgSrc);
                multimedia.put(cid, dataSource);
                continue;
            }
            DataSource dataSource = new FileDataSource(imgSrc);
            multimedia.put(cid, dataSource);

        }
    }

    /**
     * 处理 HTML 中的 <video> 标签，将视频转为 Base64 编码
     *
     * @param document HTML 文档对象
     */
    private void processVideoTags(Document document, Map<String, DataSource> multimedia) {
        Elements videoTags = document.select("video source");
        for (Element video : videoTags) {
            String cid = String.valueOf(UUID.randomUUID());
            String videoSrc = video.attr("src");
            video.attr("src", "cid:" + cid);
            video.attr("type", "video/mp4");
            if (videoSrc.startsWith("http") || videoSrc.startsWith("https")) {
                DataSource dataSource = getDataSource(videoSrc);
                multimedia.put(cid, dataSource);
                continue;
            }
            String newVideoSrc = url + videoSrc.replaceFirst(baseUrl, "");
            DataSource dataSource = new FileDataSource(newVideoSrc);
            multimedia.put(cid, dataSource);
        }
    }


    private static DataSource getDataSource(String src) {
        try {
            // 创建 URL 对象
            URI uri = new URI(src);
            // 将 URI 转换为 URL 对象
            URL url = uri.toURL();
            // 使用 URLDataSource 来处理网络资源
            return new URLDataSource(url);
        } catch (URISyntaxException | MalformedURLException e) {
            throw new RuntimeException("文件读取错误,请检查邮件内容！");
        }
    }
}
